# == Schema Information
#
# Table name: log_code_histories
#
#  id         :integer          not null, primary key
#  mobile     :string(255)
#  code_type  :integer
#  code_num   :integer
#  status     :integer
#  user_id    :integer
#  ip         :string(255)
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Log::CodeHistory < ApplicationRecord
  # 两分钟内最多获取验证码次数
  MAX_COUNT_PER_2_MIN = 3

  extend Enumerize
  # 注册，忘记密码，登陆
  CODE_TYPE = { register: 1, reminder: 2, login: 3 }
  enumerize :code_type, in: CODE_TYPE,  predicates: {prefix: true}, scope: true
  # 等待发送，已发送，已完成验证
  STATUS = { waiting: 1, sended: 2, ending: 3}
  enumerize :status, in: STATUS,  predicates: {prefix: true}, scope: true

  validate :check_send_count, on: :create
  after_create :do_send_code

  def self.send_code(mobile, type)
    return false if mobile.blank? || type.blank? || !/^1[34578]\d{9}$/===mobile.to_s || !CODE_TYPE.values.include?(type.to_i)
    # dev先用1234
    code_num = (rand*10000).to_i
    self.create(mobile: mobile, code_num: code_num, code_type: type )
  end


  protected

  def self.validate_code(mobile, type, code = nil)
    return false if mobile.blank?
    r = self.where(mobile: mobile, code_type: type.to_i).where(['created_at>=?',Time.now-10.minutes]).order('id desc').first
    if r.blank?
      r && r.code_num
    else
      r && r.code_num.to_i == code.to_i
    end
  end

  # 同一个ip/手机号不能发送过多次数
  def check_send_count
    count = Log::CodeHistory.where(mobile: self.mobile, code_type: self.code_type).where(['created_at>=?',Time.now-2.minutes]).count(:id)
    if count >= Log::CodeHistory::MAX_COUNT_PER_2_MIN
      errors.add(:id, "两分钟内最多发送#{Log::CodeHistory::MAX_COUNT_PER_2_MIN}次验证码")
    end
  end

  def do_send_code
    if Rails.env=='production'
      #todo 用sidekiq发验证码
      r = Sms.send_code(self.mobile,self.code_num)
      if r['success']
        self.update(status: Log::CodeHistory::STATUS[:sended])
      else
        Rails.logger.info r
      end
    else
      self.update(status: Log::CodeHistory::STATUS[:sended])
    end
  end
end
